import got from 'got';
import * as crypto from 'crypto';

interface Result {
  success: boolean;
  message: string;
}

interface LoginResult extends Result {
  token: string;
  password: string;
  user: {
    nickname: string;
    headImage: string;
  };
}

interface CreateResult extends Result {
  fileId: string;
}

interface File {
  _id: string;
  /** 用户id */
  userId: string;
  /** 脑图数据 */
  data: string;
  /** 脑图名称 */
  name: string;
  /** 创建时间 */
  createTime: string;
  /** 上次更新时间 */
  updateTime: string;
  /** 删除时间 */
  deleteTime: string;
  /** 回收站标识 */
  deleteFlag: boolean;
}

interface GetFileResult extends Result {
  list: File[];
}

interface GetFileDataResult extends Result {
  file: File;
}

export class Server {
  private token: string;
  /**
   * 服务
   * @param url 服务地址
   */
  constructor(public url: string) { }

  /**
   * 登录
   * @param username 用户名
   * @param password 密码
   */
  public async login(username: string, password: string | { md5: string }) {
    password = typeof password === 'string' ? crypto.createHash('md5').update(password).digest('hex') : password.md5;
    const result = (await got.post<LoginResult>(`${ this.url }/login`, {
      json: { username, password },
      responseType: 'json',
    })).body;
    result.password = password;
    this.token = result.token;
    return result;
  }

  /**
   * 注销登录
   * @param username 用户名
   * @param password 密码
   */
  public async logout() {
    return (await got.post<Result>(`${ this.url }/logout`, {
      responseType: 'json',
    })).body;
  }

  /**
   * 查询文件列表
   */
  public async getFileList() {
    return (await got.post<GetFileResult>(`${ this.url }/list?token=${ this.token }`, {
      json: { deleteFlag: false },
      responseType: 'json',
    })).body;
  }

  /**
   * 查询回收站列表
   */
  public async getRecycleList() {
    return (await got.post<GetFileResult>(`${ this.url }/list?token=${ this.token }`, {
      json: { deleteFlag: true },
      responseType: 'json',
    })).body;
  }

  /**
   * 获取文件内容
   */
  public async getFileData(fileId) {
    return (await got.post<GetFileDataResult>(`${ this.url }/get-file-data?token=${ this.token }`, {
      json: { fileId },
      responseType: 'json',
    })).body;
  }

  /**
   * 创建文件
   * @param name 文件名
   * @param data json对象
   */
  public async createFile(name: string, data: string) {
    return (await got.post<CreateResult>(`${ this.url }/create?token=${ this.token }`, {
      json: { name, data },
      responseType: 'json',
    })).body;
  }

  /**
   * 更新文件名
   * @param fileId 文件id
   * @param name 新文件名
   */
  public async renameFile(fileId: string, name: string) {
    return (await got.post<Result>(`${ this.url }/update?token=${ this.token }`, {
      json: { _id: fileId, name },
      responseType: 'json',
    })).body;
  }

  /**
   * 更新文件内容
   * @param fileId 文件id
   * @param data json对象
   */
  public async updateFileData(fileId: string, data: string) {
    return (await got.post<Result>(`${ this.url }/update?token=${ this.token }`, {
      json: { _id: fileId, data },
      responseType: 'json',
    })).body;
  }

  /**
   * 彻底删除一个文件
   * @param fileId 文件id
   */
  public async deleteFile(fileId: string) {
    return (await got.post<Result>(`${ this.url }/delete?token=${ this.token }`, {
      json: { _id: fileId },
      responseType: 'json',
    })).body;
  }

  /**
   * 将文件移动至回收站
   * @param fileId 文件id
   */
  public async recycleFile(fileId: string) {
    return (await got.post<Result>(`${ this.url }/recycle?token=${ this.token }`, {
      json: { _id: fileId },
      responseType: 'json',
    })).body;
  }

  /**
   * 清空回收站
   * @param _id 文件id
   */
  public async clearRecycle() {
    return (await got.post<Result>(`${ this.url }/clearRecycle?token=${ this.token }`, {
      responseType: 'json',
    })).body;
  }

  /**
   * 将文件从回收站还原
   * @param fileId 文件id
   */
  public async revertFile(fileId: string) {
    return (await got.post<Result>(`${ this.url }/revert?token=${ this.token }`, {
      json: { _id: fileId },
      responseType: 'json',
    })).body;
  }
}